package com.zl.protocol.des;


public class ChangeKeyUtils {

    private  DesUtils des = new DesUtils();

    private int key1_table[][] = {
            {181, 122, 128, 48, 250, 196, 118, 143, 15, 225, 250, 38, 248, 139, 155, 207},
            {17, 63, 76, 60, 244, 37, 176, 172, 135, 204, 27, 60, 220, 113, 161, 119},
            {199, 206, 79, 178, 226, 193, 31, 141, 236, 39, 35, 59, 210, 237, 117, 215},
            {64, 212, 85, 145, 127, 87, 229, 222, 215, 55, 27, 169, 77, 182, 175, 76},
            {166, 63, 81, 148, 161, 174, 10, 76, 52, 105, 61, 196, 192, 174, 223, 200},
            {135, 100, 150, 148, 74, 157, 241, 210, 249, 123, 13, 59, 129, 252, 180, 194},
            {150, 244, 93, 229, 84, 158, 111, 64, 218, 69, 239, 91, 114, 53, 229, 164},
            {165, 172, 18, 92, 25, 202, 13, 123, 104, 32, 10, 144, 237, 155, 43, 228},
            {40, 33, 186, 237, 11, 195, 170, 16, 117, 103, 124, 94, 140, 125, 92, 113},
            {187, 175, 96, 65, 48, 63, 182, 49, 141, 65, 182, 137, 162, 140, 125, 116},
            {231, 129, 242, 199, 99, 92, 29, 136, 94, 69, 34, 115, 202, 104, 192, 200},
            {221, 124, 36, 84, 181, 244, 183, 20, 144, 18, 51, 114, 64, 68, 144, 139},
            {131, 12, 170, 31, 175, 22, 185, 108, 115, 152, 171, 65, 58, 173, 160, 83},
            {234, 139, 110, 67, 15, 178, 41, 54, 178, 155, 205, 51, 255, 237, 196, 26},
            {157, 139, 178, 67, 31, 92, 41, 92, 178, 144, 94, 206, 144, 140, 113, 192},
    };

    //KEY0 密码
    private int key0_table[] = {157, 139, 178, 67, 15, 178, 41, 54, 178, 155, 205, 51, 255, 237, 196, 26};
    private int dat_out[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


    private byte data_out[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    public byte[] getData_out() {
        return data_out;
    }

    public String getStrHexByDat_out() {
        return intArrayToHexStr(dat_out);
    }

    /**
     * 格式化数据使用
     *
     * @param dat_in
     * @param mode   0 加密 1解密
     * @return
     */
    public int Format_Init(int dat_in[], int mode) {
        int keyL[] = {0, 0, 0, 0, 0, 0, 0, 0};
        int keyR[] = {0, 0, 0, 0, 0, 0, 0, 0};

        int bufIL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据
        int bufOL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据

        int bufIR[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据
        int bufOR[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据

        String buffer = "";


        int i = 0;

        if (dat_in[0] == 0x21) {
        } else {
            return 1;
        }

        for (i = 0; i < 8; i++) {
            //
            keyL[i] = key0_table[i];
            keyR[i] = key0_table[i + 8];
            //
            bufIL[i] = dat_in[i];
            bufIR[i] = dat_in[i + 8];
        }

        //3DES_加密
        if (mode == 0) {

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 1);
            bufIL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);


            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 1);
            bufIR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);
        } else {
            //3DES_解密
            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 0);
            bufIL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 0);
            bufIR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);
        }

        for (i = 0; i < 8; i++) {
            dat_out[i] = bufOL[i];
            dat_out[i + 8] = bufOR[i];
        }

        return 0;
    }

    /**
     * 格式化数据使用
     *
     * @param dat_in
     * @param keyid
     * @param mode   0 加密 1解密
     * @return
     */
    private int Restore_Factory(int[] dat_in,int keyid, int mode) {
        int keyL[] = {0, 0, 0, 0, 0, 0, 0, 0};
        int keyR[] = {0, 0, 0, 0, 0, 0, 0, 0};

        int bufIL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据
        int bufOL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据

        int bufIR[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据
        int bufOR[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据

        String buffer = "";

        int i = 0;

        for (i = 0; i < 8; i++) {
            //
            keyL[i] = key0_table[i];
            keyR[i] = key0_table[i + 8];
            //
            bufIL[i] = dat_in[i];
            bufIR[i] = dat_in[i + 8];
        }

        //3DES_加密
        if (mode == 0) {

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 1);
            bufIL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);


            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 1);
            bufIR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);
        } else {
            //3DES_解密
            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 0);
            bufIL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 0);
            bufIR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);
        }

        //第一次输出
        for (i = 0; i < 8; i++) {
            dat_out[i] = bufOL[i];
            dat_out[i + 8] = bufOR[i];
        }

        //System.out.println("K0_Encrypt:"+intArrayToHexStr(dat_out));

        for(i=0;i<8;i++)
        {//第一次赋值
            dat_in[i]   = dat_out[i];
            dat_in[i+8] = dat_out[i+8];
        }

        //再key1搞一把
        for(i=0;i<8;i++)
        {
            //
            keyL[i]  = key1_table[keyid][i];
            keyR[i]  = key1_table[keyid][i+8];
            //
            bufIL[i] = dat_in[i];
            bufIR[i] = dat_in[i+8];
        }

        if (mode == 0) {

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 1);
            bufIL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);


            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 1);
            bufIR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);
        } else {
            //3DES_解密
            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 0);
            bufIL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 0);
            bufIR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);
        }

        for(i=0;i<8;i++)
        {
            dat_out[i]   = bufOL[i];
            dat_out[i+8] = bufOR[i];
        }
        //System.out.println("K1_Encrypt:"+intArrayToHexStr(dat_out));
        return 0;
    }

    public int Restore_Factory(String dat_in_hex, int keyid, int mode) {
        return Restore_Factory(HexStrTointArray(dat_in_hex),keyid,mode);
    }


    /*********************************************************************************************************
     三重DES加密/解密
     *********************************************************************************************************/
    public int TripleDes_uint16(int dat_in[], int keyid, int mode) {

        int keyL[] = {0, 0, 0, 0, 0, 0, 0, 0};
        int keyR[] = {0, 0, 0, 0, 0, 0, 0, 0};

        int bufIL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据
        int bufOL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据

        int bufIR[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据
        int bufOR[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据

        String buffer = "";
        int i = 0;

        for (i = 0; i < 8; i++) {
            //
            keyL[i] = key1_table[keyid][i];
            keyR[i] = key1_table[keyid][i + 8];
            //
            bufIL[i] = dat_in[i];
            bufIR[i] = dat_in[i + 8];
        }

        if (mode == 0) {
            //3DES_加密
            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 1);
            bufIL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 0);
            bufOL = HexStrTointArray(buffer);


            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 1);
            bufIR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 0);
            bufOR = HexStrTointArray(buffer);
        } else {
            //3DES_解密
            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOL), intArrayToHexStr(keyR), 0);
            bufIL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIL), intArrayToHexStr(keyL), 1);
            bufOL = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);

            //DesExeEncrypt(bufOR, keyR, bufIR);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(intArrayToHexStr(bufOR), intArrayToHexStr(keyR), 0);
            bufIR = HexStrTointArray(buffer);

            //DesExeDecrypt(bufIR, keyL, bufOR);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(intArrayToHexStr(bufIR), intArrayToHexStr(keyL), 1);
            bufOR = HexStrTointArray(buffer);
        }

        for (i = 0; i < 8; i++) {
            dat_out[i] = bufOL[i];
            dat_out[i + 8] = bufOR[i];
        }
        return 0;
    }


    /*********************************************************************************************************
     三重DES加密/解密
     这个是对8个字节运算,已符合标准的了
     本文内使用。
     *********************************************************************************************************/
    private byte[] TripleDes_uint8(final byte[] keyL, final byte[] keyR, byte[] dat, int mode) {

        byte bufIL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据
        byte bufOL[] = {0, 0, 0, 0, 0, 0, 0, 0};   //  缓冲数据

        int i = 0;
        String buffer = "";

        for (i = 0; i < 8; i++) {
            bufIL[i] = dat[i];
        }

        if (mode == 0) {

            //3DES_加密
            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(Bytes2HexString(bufIL), Bytes2HexString(keyL), 0);
            bufOL = HexString2Bytes(buffer);

            //DesExeDecrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(Bytes2HexString(bufOL), Bytes2HexString(keyR), 1);
            bufIL = HexString2Bytes(buffer);

            //DesExeEncrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(Bytes2HexString(bufIL), Bytes2HexString(keyL), 0);
            bufOL = HexString2Bytes(buffer);

        } else {
            //3DES_解密
            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(Bytes2HexString(bufIL), Bytes2HexString(keyL), 1);
            bufOL = HexString2Bytes(buffer);

            //DesExeEncrypt(bufOL, keyR, bufIL);       //  解密：buf[]＋keyR[]→dat[]
            buffer = des.DES_1(Bytes2HexString(bufOL), Bytes2HexString(keyR), 0);
            bufIL = HexString2Bytes(buffer);

            //DesExeDecrypt(bufIL, keyL, bufOL);       //  加密：dat[]＋keyL[]→buf[]
            buffer = des.DES_1(Bytes2HexString(bufIL), Bytes2HexString(keyL), 1);
            bufOL = HexString2Bytes(buffer);
        }

        for (i = 0; i < 8; i++) {
            dat[i] = bufOL[i];
        }
        return dat;
    }


    //加密应用
    public int JM_3DES(byte comd, byte[] SN, byte[] data_in, byte[] key2, int keyid) {
        int i, j, k;
        byte COMD;
        byte RNS0;
        byte RNS1;
        //byte SUMX = 0;
        byte Byte_15 = 0;

        byte data_b[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        byte BufJ[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte BufR[] = {0, 0, 0, 0, 0, 0, 0, 0};

        byte Key2_A[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_B[] = {0, 0, 0, 0, 0, 0, 0, 0};

        byte Key2_1[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_2[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_3[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_4[] = {0, 0, 0, 0, 0, 0, 0, 0};


        //加密过程
        //命令
        COMD = comd;
        //加密时，最后三个字节为固定RNS0,RNS1,SUMX

        RNS0 = data_in[14];
        RNS1 = data_in[15];
        //SUMX = data_in[15];//这个由外面计算好


        //在变形加密前就做好校验
        //for (i = 0; i < 15; i++) {
        //    SUMX = (byte) (SUMX + data_in[i]);
        //}

        //data_in[15] = SUMX;//
        //System.out.println("data_b:" + Bytes2HexString(data_in[15]));

        //变形
        for (i = 0; i < 16; i++) {//
            data_b[i] = (byte) (data_in[i] ^ RNS0 ^ RNS1 ^ (0xFF - keyid));
        }

        data_b[14] = RNS0;
        data_b[15] = RNS1;

        //System.out.println("data_b:" + Bytes2HexString(data_b));
        //插队
        for (i = 15; i > (keyid + 1); i--) {//从尾巴向前扯开两个字节
            data_b[i] = data_b[i - 2];
        }
        //插队
        data_b[keyid + 0] = RNS0;
        data_b[keyid + 1] = RNS1;
        //data_b[keyid + 2] = SUMX;
        Byte_15 = data_b[15];
        //SUMX = data_b[15];//在这里取就是变形过后取,用于做密钥

        //对16个字节进行分组
        j = 0;
        k = 0;
        for (i = 0; i < 16; i++) {
            //分成奇偶数组
            if ((i % 2) == 0) {//偶
                BufR[j] = data_b[i];//[0,2,4..14]
                j++;
            } else {//奇
                BufJ[k] = data_b[i];//[1,3,5..15]
                k++;
            }
        }

        //算出四个要用到的KEY
        for (i = 0; i < 8; i++) {
            Key2_A[i] = key2[i + 0];
            Key2_B[i] = key2[i + 8];

            Key2_1[i] = (byte) (Key2_A[i] ^ SN[i]);
            Key2_2[i] = (byte) (Key2_B[i] ^ COMD);

            Key2_3[i] = (byte) (Key2_A[i] ^ Byte_15);//这个SUMX已固定在  data_in[15];
            Key2_4[i] = (byte) (Key2_B[i] ^ (keyid ^ 0x5A));
        }

        //System.out.println("Key2_1:" + Bytes2HexString(Key2_1));
        //System.out.println("Key2_2:" + Bytes2HexString(Key2_2));

        //对数据进行加密
        //TripleDes_uint8(Key2_1, Key2_2, BufJ, DES_ENCRYPT);//对 15 - 1加密
        BufJ = TripleDes_uint8(Key2_1, Key2_2, BufJ, 0);//对 15 - 1加密

        //System.out.println("BufJ:" + Bytes2HexString(BufJ));

        //TripleDes_uint8(Key2_3, Key2_4, BufR, DES_ENCRYPT);//对 14 - 0加密
        BufR = TripleDes_uint8(Key2_3, Key2_4, BufR, 0);//对 14 - 0加密

        //System.out.println("BufR:" + Bytes2HexString(BufR));


        //对数据重排，输出去
        for (i = 0; i < 8; i++) {
            data_out[2 * i + 0] = BufR[i];
            data_out[2 * i + 1] = BufJ[i];
        }

        return 0;
    }

    //解密应用
    public int MJ_3DES(byte comd, byte[] SN, byte[] data_in, byte[] key2, int keyid) {
        int i, j, k;
        byte COMD;
        byte RNS0;
        byte RNS1;
        //byte SUMX = 0;
        byte Byte_15 = 0;

        byte data_b[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        byte BufJ[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte BufR[] = {0, 0, 0, 0, 0, 0, 0, 0};

        byte Key2_A[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_B[] = {0, 0, 0, 0, 0, 0, 0, 0};

        byte Key2_1[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_2[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_3[] = {0, 0, 0, 0, 0, 0, 0, 0};
        byte Key2_4[] = {0, 0, 0, 0, 0, 0, 0, 0};

        //对密文16个字节进行分组
        //对密文16个字节进行分组
        j = 0;
        k = 0;
        for (i = 0; i < 16; i++) {
            //分成奇偶数组
            if ((i % 2) == 0) {//偶
                BufR[j] = data_in[i];//[0,2,4..14]
                j++;
            } else {//奇
                BufJ[k] = data_in[i];//[1,3,5..15]
                k++;
            }
        }

        COMD = comd;
        //算出四个要用到的KEY
        for (i = 0; i < 8; i++) {
            Key2_A[i] = key2[i + 0];
            Key2_B[i] = key2[i + 8];

            Key2_1[i] = (byte) (Key2_A[i] ^ SN[i]);
            Key2_2[i] = (byte) (Key2_B[i] ^ COMD);

            //Key2_3[i] = Key2_A[i] ^ SUMX;//这个需要在偶字节解密时重新赋一下值
            Key2_4[i] = (byte) (Key2_B[i] ^ (keyid ^ 0x5A));
        }

        //对奇字节解密
        BufJ = TripleDes_uint8(Key2_1, Key2_2, BufJ, 1);//对 15 - 1解密
        Byte_15 = BufJ[7];//也就是原数据的15号字节

        for (i = 0; i < 8; i++) {
            Key2_3[i] = (byte) (Key2_A[i] ^ Byte_15);//这个需要在偶字节解密时重新赋一下值
        }
        //对偶字节解密
        BufR = TripleDes_uint8(Key2_3, Key2_4, BufR, 1);//对 14 - 0解密

        //又拼成0..15
        for (i = 0; i < 8; i++) {
            data_b[2 * i + 0] = BufR[i];
            data_b[2 * i + 1] = BufJ[i];
        }

        //反变形
        RNS0 = data_b[keyid + 0];
        RNS1 = data_b[keyid + 1];
        //SUMX = data_b[keyid + 2];//不参与变形
        for (i = 0; i < 16; i++) {
            data_b[i] = (byte) (data_b[i] ^ RNS0 ^ RNS1 ^ (0xFF - keyid));
        }
        //SUMX = data_b[keyid+2];

        //抽出这三个字节，其它前靠
        for (i = keyid; i < 16; i++) {
            data_b[i] = data_b[i + 1 + 1];
        }
        data_b[14] = RNS0;
        data_b[15] = RNS1;
        //data_b[15] = SUMX;

        //System.out.println("data_b:" + Bytes2HexString(data_b));


        //对数据重排，输出去
        for (i = 0; i < 16; i++) {
            data_out[i] = data_b[i];
        }

        //在变形加密前就做好校验，确定一下校验
        //SUMX = 0;
        //for (i = 0; i < 15; i++) {
        //    SUMX = (byte) (SUMX + data_out[i]);
        //}

//        if (Bytes2HexString(SUMX).equals(Bytes2HexString(data_out[15]))) {
//            //再对比一下命令字
//            if (Bytes2HexString(COMD).equals(Bytes2HexString(data_out[0]))) {
//                return 0;
//            } else {
//                return 2;
//            }
//        } else {
//            return 1;
//        }
        //再对比一下命令字
        if (Bytes2HexString(COMD).equals(Bytes2HexString(data_out[0]))) {
            return 0;
        } else {
            return 2;
        }

    }


    /**
     * 将数字数组转换为字节串
     *
     * @param array
     * @return
     */
    private String intArrayToHexStr(int[] array) {
        String hex = "";
        for (int i = 0; i < array.length; i++) {
            String temp = Integer.toHexString(array[i]);
            if (1 == temp.length())
                temp = "0" + temp;
            hex += temp.toUpperCase();

        }
        return hex;
    }

    /**
     * 将数字数组转换为字节串
     *
     * @param HexStr
     * @return
     */
    private int[] HexStrTointArray(String HexStr) {
        int length = HexStr.length() / 2;
        int[] array = new int[length];

        for (int i = 0; i < length; i++) {
            String temp = HexStr.substring(i * 2, i * 2 + 2);
            array[i] = Integer.valueOf(temp, 16);
        }

        return array;
    }



    /**
     * 将16位的字节串，返回16位字符串
     *
     * @param b byte[] 字节串 例：0x0B;
     * @return String 返回 0x0B&0xFF 0x0B Integer.toHexString(0x0B&0xFF)
     * &与(两个相应位都为1 则为1，否为0) 若高位有零，得值为b,则高位补0为0B;
     */
    public String Bytes2HexString(byte[] b) {
        String ret = "";
        for (int i = 0; i < b.length; i++) {

            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase();
        }
        return ret;
    }


    /**
     * 将指定字符串src，以每两个字符分割转换为16进制形式 如："2B44EFD9" --> byte[]{0x2B, 0x44, 0xEF,
     * 0xD9}
     *
     * @param src String
     * @return byte[]
     */
    public byte[] HexString2Bytes(String src) {
        byte[] ret = new byte[src.length() / 2];
        byte[] tmp = src.getBytes();
        for (int i = 0; i < src.length() / 2; i++) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }
        return ret;
    }

    /**
     * 将两个ASCII字符合成一个字节； 如："EF"--> 0xEF
     *
     * @param src0 byte 第一位向左移位4 例:2<<4 0x02 00000010=2 0x20 00100000=32
     * @param src1 byte 第二位按正常操作 例:0x0B 00001011
     * @return byte 返回两个ASCII字符的十六进制 例:0x20^0x0B的按位异或(两面相应位相同，则0，否则1) 0x2B
     * 00100000^00001011=00101011
     */
    public byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0}))
                .byteValue();
        // byte _b0=src0;
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1}))
                .byteValue();
        // byte _b1=src1;
        byte ret = (byte) (_b0 ^ _b1);
        return ret;
    }

    /**
     * 字符串src 以"2B" 转换为 0x2B 若 "2Z" 则报错。
     *
     * @param src
     * @return
     */
    public byte HexString2Byte(String src) {
        byte[] tmp = src.getBytes();
        return uniteBytes(tmp[0], tmp[1]);
        // return Byte.decode("0x" + src).byteValue();
    }

    /**
     * 将16位的字节，返回16位字符串
     *
     * @param b byte[] 字节串 例：0x0B;
     * @return String 返回 0x0B&0xFF 0x0B Integer.toHexString(0x0B&0xFF)
     * &与(两个相应位都为1 则为1，否为0) 若高位有零，得值为b,则高位补0为0B;
     */
    public String Bytes2HexString(byte b) {
        String ret = "";

        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;
        }
        ret += hex.toUpperCase();
        return ret;
    }

    public static void main(String[] args) {

        int key[]={0x9D,0x8B,0xB2,0x43,0x1F,0x5C,0x29,0x5C,0xB2,0x90,0x5E,0xCE,0x90,0x8C,0x71,0xC0};

        System.out.print("{");
        for(int i=0;i<16;i++)
        {
            System.out.print(key[i]+",");
        }
        System.out.println("}");
        String cmd = "13";
        String sn = "6C228B34DEE61252";
        String Key2 = "52A478351F09161718191A1B1C1D1E1F";
        String InData = "1312345678190529142344B400645335";
                       //1312345678190529142344B400645335

        ChangeKeyUtils ck = new ChangeKeyUtils();
        int start = ck.JM_3DES(ck.HexString2Byte(cmd), ck.HexString2Bytes(sn), ck.HexString2Bytes(InData), ck.HexString2Bytes(Key2), 0);
        String mmdate = ck.Bytes2HexString(ck.data_out);
        System.out.println(mmdate);

        start = ck.MJ_3DES(ck.HexString2Byte(cmd), ck.HexString2Bytes(sn), ck.HexString2Bytes(mmdate), ck.HexString2Bytes(Key2), 0);
        System.out.println(start);
        mmdate = ck.Bytes2HexString(ck.data_out);
        System.out.println(mmdate);

    }
}
